using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using FireStarter.CodeGeneration;
using FireStarterModeller.BO;
using NUnit.Framework;

namespace FireStarter.Test.CodeGeneration
{
    [TestFixture]
    public abstract class TestProjectGeneratorBase_GeneratedFile : TestBase
    {
        protected abstract string GetFileName();

        protected abstract IProjectGenerator CreateProjectReadyToGenerate();

        [Test]
        public void TestGenerate_GeneratesFile_IfDoesNotExist()
        {
            //---------------Set up test pack-------------------
            IProjectGenerator projectGenerator = CreateProjectReadyToGenerate();
            string fileName = Path.Combine(projectGenerator.ProjectPath, GetFileName());
            //---------------Assert Precondition----------------
            Assert.IsFalse(File.Exists(fileName));
            //---------------Execute Test ----------------------
            projectGenerator.Generate();
            //---------------Test Result -----------------------
            Assert.IsTrue(Directory.Exists(projectGenerator.ProjectPath), "Folder should exist.");
            Assert.IsTrue(File.Exists(fileName), "File should have been generated because it didn't exist.");
        }

        [Test]
        public void TestGenerate_GeneratesFileCorrectly()
        {
            //---------------Set up test pack-------------------
            IProjectGenerator projectGenerator = CreateProjectReadyToGenerate();
            string fileName = Path.Combine(projectGenerator.ProjectPath, GetFileName());
            //---------------Assert Precondition----------------
            Assert.IsFalse(File.Exists(fileName));
            //---------------Execute Test ----------------------
            projectGenerator.Generate();
            //---------------Test Result -----------------------
            Assert.IsTrue(Directory.Exists(projectGenerator.ProjectPath), "Folder should exist.");
            Assert.IsTrue(File.Exists(fileName), "File should have been generated because it didn't exist.");
            string fileContents = File.ReadAllText(fileName);
            AssertFileGeneratedCorrectly(projectGenerator, fileContents);
        }

        protected abstract void AssertFileGeneratedCorrectly(IProjectGenerator projectGenerator, string fileContents);

        [Test]
        public void TestGenerate_DoesntRegenerate_IfExists()
        {
            //---------------Set up test pack-------------------
            IProjectGenerator projectGenerator = CreateProjectReadyToGenerate();
            projectGenerator.Generate();
            string fileName = Path.Combine(projectGenerator.ProjectPath, GetFileName());
            string tempFileContents = GetRandomString();
            File.WriteAllText(fileName, tempFileContents);
            //---------------Assert Precondition----------------
            Assert.AreEqual(tempFileContents, File.ReadAllText(fileName));
            //---------------Execute Test ----------------------
            projectGenerator.Generate();
            //---------------Test Result -----------------------
            Assert.AreEqual(tempFileContents, File.ReadAllText(fileName));
        }

        [Test]
        public void TestFileAddedToProject()
        {
            //---------------Set up test pack-------------------
            IProjectGenerator projectGenerator = CreateProjectReadyToGenerate();
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            projectGenerator.Generate();
            //---------------Test Result -----------------------
            ProjectFileManager projectFileManager = new ProjectFileManager(projectGenerator.ProjectFileName, OutputType.Library, CodeTemplateEnum.CSharpVisualStudio2005);
            string fileName = Path.Combine(projectGenerator.ProjectPath, GetFileName());
            Assert.IsTrue(CheckProjectHasFile(projectFileManager, fileName), "File Should be added to the project.");
        }

        protected virtual bool CheckProjectHasFile(ProjectFileManager projectFileManager, string fileName)
        {
            return projectFileManager.HasCodeFile(fileName);
        }
    }
}
